/**
 * @file	BLDC.c
 * @purpose	Initializing and controlling BLDC motor
 * @brief	BLDC motor control initialization and controlling file
 * @version	1.0
 * @date	29 July 2009
 * @author	nlv15840
*/
/*----------------------------------------------------------------------------
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 **********************************************************************/

#include "Application.h"


/************************** PRIVATE VARIABLES *************************/
/**
 * @addtogroup PRIVATE_VARIABLES
 * @{
 */

/* Pin configuration data */
/** Motor Control Channel 0 Output A */
const PINSEL_CFG_Type mcpwm_mco0a_pin[1] = {{1, 19, 1, 0, 0}};
/** Motor Control Channel 0 Output B */
const PINSEL_CFG_Type mcpwm_mco0b_pin[1] = {{1, 22, 1, 0, 0}};

/** Motor Control Low-active abort feed back */
const PINSEL_CFG_Type mcpwm_mcabort_pin[1] = {{ 1, 21, 1, 0, 0}};

/** @brief MCPWM Channel configuration data */
MCPWM_CHANNEL_CFG_Type channelsetup[3];

/**
 * @}
 */

/**
 * @defgroup MOTOR_VARIABLES
 * @{
 */

/** Motor controlling structure */
volatile PIDstr PID_Motor
= {
/* PID_Motor.p           */ 0,	//3
/* PID_Motor.i           */ 0,	//1
/* PID_Motor.d           */ 0,	//0.5
/* PID_Motor.sp          */ 0,	//1000
/* PID_Motor.pv          */ 0,
/* PID_Motor.err[3]      */ {0,0,0},
/* PID_Motor.mv          */ 0,

/* PID_Motor.CMT_CNT     */ 0,

/* PID_Motor.RPM         */ 0,
/* PID_Motor.Enable      */ DISABLE,
/* PID_Motor.Direction   */ CW,
/* PID_Motor.Brake       */ DISABLE,
/* PID_Motor.Period      */ 2000,
/* PID_Motor.Poles       */ 1,

};
/**
 * @brief	Initialize the system to control the Brushless DC motor
 * @par		Pin settings:
 *			- P1.19 = MC0A
 *			- P1.22 = MC0B
 *			- P1.25 = MC1A
 *			- P1.26 = MC1B
 *			- P1.28	= MC2A
 *			- P1.29 = MC2B
 *			- P1.20 = MCFB0
 *			- P1.23 = MCFB1
 *			- P1.24 = MCFB2
 *			- P1.21 = MCABORT
 * @par	Channel settings:
 *			- Type = edge mode
 *			- Polarity = Low passive
 *			- Deadtime = disabled
 *			- Deadtime value = 0
 */
void BLDC_Init1 (void)
{
#if (USE_QEI == 1)
	/* QEI configuration structure variable */
	QEI_CFG_Type QEIConfigStruct;

#endif

    /* MCPWM INITIALIZATION *******************************************/
    /* Initializes pin corresponding to MCPWM function */
   // PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco0a_pin[0]);
    PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco0a_pin[0]);
    PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco0b_pin[0]);
   // PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mcabort_pin[0]);
    /* Init MCPWM peripheral */
    MCPWM_Init(MCPWM);

    /* MCPWM Channel 0 setup */
    channelsetup[0].channelType = MCPWM_CHANNEL_EDGE_MODE;
    channelsetup[0].channelPolarity = MCPWM_CHANNEL_PASSIVE_LO;
    channelsetup[0].channelDeadtimeEnable = DISABLE;
    channelsetup[0].channelDeadtimeValue = 0;
    channelsetup[0].channelUpdateEnable = ENABLE;
    channelsetup[0].channelTimercounterValue = 0;
    channelsetup[0].channelPeriodValue = PID_Motor.Period;
    channelsetup[0].channelPulsewidthValue = 1500;

    /* Apply the setup to the channels */
    MCPWM_ConfigChannel(MCPWM, 0, &channelsetup[0]);	//dua gia tri setup tren vao thanh ghi cua chanel[0]

#if (USE_QEI == 1)
	/* QEI CONFIGURATION **********************************************/
	/* Configure the QEI */
	QEIConfigStruct.CaptureMode = QEI_CAPMODE_4X;
	QEIConfigStruct.DirectionInvert = QEI_DIRINV_NONE;
	QEIConfigStruct.InvertIndex = QEI_INVINX_NONE;
	QEIConfigStruct.SignalMode = QEI_SIGNALMODE_QUAD;
	/* Initialize the QEI */
	QEI_Init(QEI, &QEIConfigStruct);
	/* Set the QEI Filter clock counter*/
	QEI_SetDigiFilter(QEI, 20);
	/* Set the max QEI position */
//	QEI_SetMaxPosition(QEI, 2000);
	QEI->QEICON = (1<<1);

	/* Enable interrupt for velocity Timer overflow for capture velocity into Acc */
	QEI_IntCmd(QEI, QEI_INTFLAG_TIM_Int, ENABLE);
	/* preemption = 1, sub-priority = 1 */
	NVIC_SetPriority(QEI_IRQn, ((0x01<<3)|0x01));
	/* Enable interrupt for QEI  */
	NVIC_EnableIRQ(QEI_IRQn);

#endif // END OF USE_QEI


}

/**
 *	@brief
 * 			This function enables the BLDC motor control by setting the MCPWM in the
 *			right mode, enable the capturing and starting the MCPWM
 */
void BLDC_Enable (void)
{

    /* Enable the MCPWM DC mode and all output pins */
    MCPWM_DCMode(MCPWM, DISABLE, DISABLE, ( 0 ));

    /* Set the PWM output value */
    channelsetup[0].channelPulsewidthValue = 1500;

    /* Write to the shadow register */
    MCPWM_WriteToShadow(MCPWM, 0, &channelsetup[0]);

    /* Disable LIM0 and MAT0 interrupt flag */
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_LIM0, DISABLE);
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_MAT0, DISABLE);

    /* Disable LIM1 and MAT1 interrupt flag */
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_LIM1, DISABLE);
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_MAT1, DISABLE);

    /* Disable LIM2 and MAT2 interrupt flag */
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_LIM2, DISABLE);
    MCPWM_IntConfig(MCPWM, MCPWM_INTFLAG_MAT2, DISABLE);

    /* Start up the MCPWM */
    MCPWM_Start(MCPWM, ENABLE, ENABLE, ENABLE);

    /* Disable the brake */
    PID_Motor.Brake = DISABLE;

    /* Enable the motor */
    PID_Motor.Enable = ENABLE;
}

void BLDC_setDuty (unsigned int duty)
{
	/* Set the PWM output value */
	channelsetup[0].channelPulsewidthValue = duty;
   	 /* Write to the shadow register */
	MCPWM_WriteToShadow(MCPWM, 0, &channelsetup[0]);

}
void BLDC_break (void)
{

	/* Set the PWM output value */
	channelsetup[0].channelPulsewidthValue = 0;
   	 /* Write to the shadow register */
	MCPWM_WriteToShadow(MCPWM, 0, &channelsetup[0]);
}

void BLDC_commutate (unsigned char step)
{
    unsigned char pattern = 0;

    /* Check whether there is a setpoint and an enable */
    if((PID_Motor.sp == 0) || (PID_Motor.Enable == DISABLE))
    {
        /* If no setpoint and brake is enable BREAK! */
        /* let it run free */
            step = 'C';
       
    }

//	PID_Motor.mv = PID_Motor.Period/2;
 
    	BLDC_setDuty(PID_Motor.mv);

    switch (step)
	{
				  
		case 2:
			pattern = MCPWM_PATENT_A0 | MCPWM_PATENT_B0;
			break;
	    
		case 'C':
			pattern = 0;
			break;
		default:
			pattern = 0;
	}

    MCPWM->MCCCP = pattern;

}
/**
 *  @brief
 */

